package com.cy.jt.security.config;

import com.cy.jt.security.config.handler.DefaultAccessDeniedExceptionHandler;
import com.cy.jt.security.config.handler.DefaultAuthenticationEntryPoint;
import com.cy.jt.security.config.handler.JsonAuthenticationSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.server.authentication.RedirectServerAuthenticationSuccessHandler;

@Configuration
/*（1）@Configuration 此注解表示描述的类是spring中的配置类，配置类会在spring工程启动时优先加载，在配置类中通常会
对第三方资源进行初始配置。*/

@EnableGlobalMethodSecurity(prePostEnabled = true)
/*（2）@EnableGlobalMethodSecurity此注解由SpringSecurity提供，用于描述权限配置类，告诉系统底层在启动时，进行访问权限的初始化
(1)Enable-启用
(2)Global-全局
(3)Method-方法
(4)Security-安全
*/

public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * @Bean
     * 此注解通常会在@Configuration注解描述的类中描述方法，用于告诉spring框架这个方法的返回值
     * 会交给spring管理，并给spring管理的这个对象起个默认的名字，这个名字与方法名相同，当然也可以
     * 通过@Bean注解自定义名字。
     */
    @Bean
    //@Bean("brcytPassword") //自定义bean对象名字为：brcytPassword
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

 /*对http请求的安全控制进行配置,与前端登录页面进行绑定！*/
  @Override
  protected  void configure(HttpSecurity http) throws Exception{
        //1.关闭跨域攻击
         http.csrf().disable();
        //2.配置登录url(登录表单使用哪一个页面)
         http.formLogin()
                 .loginPage("/login.html") //登录页面
                 .loginProcessingUrl("/login") //与from表单中的action值相同
                 // .usernameParameter("username") 与form表单中的input框元素的name属性相同
                 // .passwordParameter("password")
                 //.successForwardUrl("/index.html") //请求转发（Controller中的一个方法）
                 //.failureForwardUrl("/login.html?error"); //登录失败（默认）
                 .defaultSuccessUrl("/index.html");//登录成功的url
                // .successHandler(new RedirectAuthenticationSuccessHandler("http://www.tedu.cn"));//重定向
                // .successHandler(new JsonAuthenticationSuccessHandler());//返回一个json数据

        //设置退出操作
      http.logout()  //开始设置登出信息
              .logoutUrl("/logout") //登出路径
              .logoutSuccessUrl("/login.html?logout"); //设置登出后显示的页面

      //设置需要认证与拒绝访问的异常处理器
      http.exceptionHandling()
              .authenticationEntryPoint(new DefaultAuthenticationEntryPoint())//未认证时
              .accessDeniedHandler(new DefaultAccessDeniedExceptionHandler());//未授权时
        //3.放行登录url(配置资源不需要认证就可以访问)
        // http.authorizeRequests().antMatchers("/login.html").permitAll();//允许直接访问
        http.authorizeRequests().antMatchers("/login.html").permitAll().anyRequest().authenticated();
        //除了以上资源(/login.html)必须认证才能访问
  }
}
